package com.zhuang.reflection;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionUtils {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
		// api_01();
		api_02();
	}

	// 第一组方法API
	public static void api_01() throws ClassNotFoundException, NoSuchMethodException {

		// 得到Class对象
		Class<?> personCls = Class.forName("com.zhuang.reflection.Person");
		// getName:获取全类名
		System.out.println(personCls.getName());// com.hspedu.reflection.Person
		// getSimpleName:获取简单类名
		System.out.println(personCls.getSimpleName());// Person
		// getFields:获取所有public修饰的属性，包含本类以及父类的
		Field[] fields = personCls.getFields();
		for (Field field : fields) {// 增强for
			System.out.println("本类以及父类的属性=" + field.getName());
		}
		// getDeclaredFields:获取本类中所有属性
		Field[] declaredFields = personCls.getDeclaredFields();
		for (Field declaredField : declaredFields) {
			System.out.println("本类中所有属性=" + declaredField.getName());
		}
		// getMethods:获取所有public修饰的方法，包含本类以及父类的
		Method[] methods = personCls.getMethods();
		for (Method method : methods) {
			System.out.println("本类以及父类的方法=" + method.getName());
		}
		// getDeclaredMethods:获取本类中所有方法
		Method[] declaredMethods = personCls.getDeclaredMethods();
		for (Method declaredMethod : declaredMethods) {
			System.out.println("本类中所有方法=" + declaredMethod.getName());
		}
		// getConstructors: 获取所有public修饰的构造器，包含本类
		Constructor<?>[] constructors = personCls.getConstructors();
		for (Constructor<?> constructor : constructors) {
			System.out.println("本类的构造器=" + constructor.getName());
		}
		// getDeclaredConstructors:获取本类中所有构造器
		Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();
		for (Constructor<?> declaredConstructor : declaredConstructors) {
			System.out.println("本类中所有构造器=" + declaredConstructor.getName());// 这里老师只是输出名
		}
		// getPackage:以Package形式返回 包信息
		System.out.println(personCls.getPackage());// com.hspedu.reflection
		// getSuperClass:以Class形式返回父类信息
		Class<?> superclass = personCls.getSuperclass();
		System.out.println("父类的class对象=" + superclass);//
		// getInterfaces:以Class[]形式返回接口信息
		Class<?>[] interfaces = personCls.getInterfaces();
		for (Class<?> anInterface : interfaces) {
			System.out.println("接口信息=" + anInterface);
		}
		// getAnnotations:以Annotation[] 形式返回注解信息
		Annotation[] annotations = personCls.getAnnotations();
		for (Annotation annotation : annotations) {
			System.out.println("注解信息=" + annotation);// 注解
		}
	}

	public static void api_02() throws ClassNotFoundException, NoSuchMethodException {
		// 得到Class对象
		Class<?> personCls = Class.forName("com.zhuang.reflection.Person");
		// getDeclaredFields:获取本类中所有属性
		// 规定 说明: 默认修饰符 是0 ， public 是1 ，private 是 2 ，protected 是 4 , static 是 8 ，final 是
		// 16
		Field[] declaredFields = personCls.getDeclaredFields();
		for (Field declaredField : declaredFields) {
			System.out.println("本类中所有属性=" + declaredField.getName() + " 该属性的修饰符值=" + declaredField.getModifiers()
					+ " 该属性的类型=" + declaredField.getType());
		}

		// getDeclaredMethods:获取本类中所有方法
		Method[] declaredMethods = personCls.getDeclaredMethods();
		for (Method declaredMethod : declaredMethods) {
			System.out.println("本类中所有方法=" + declaredMethod.getName() + " 该方法的访问修饰符值=" + declaredMethod.getModifiers()
					+ " 该方法返回类型" + declaredMethod.getReturnType());

			// 输出当前这个方法的形参数组情况
			Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
			for (Class<?> parameterType : parameterTypes) {
				System.out.println("该方法的形参类型=" + parameterType);
			}
		}

		// getDeclaredConstructors:获取本类中所有构造器
		Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();
		for (Constructor<?> declaredConstructor : declaredConstructors) {
			System.out.println("====================");
			System.out.println("本类中所有构造器=" + declaredConstructor.getName());// 这里老师只是输出名

			Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
			for (Class<?> parameterType : parameterTypes) {
				System.out.println("该构造器的形参类型=" + parameterType);
			}
		}
	}
}

class A {
	public String hobby;

	public void hi() {

	}

	public A() {
	}

	public A(String name) {
	}
}

interface IA {
}

interface IB {

}

@Deprecated
class Person extends A implements IA, IB {
	// 属性
	public String name;
	protected static int age; // 4 + 8 = 12
	String job;
	@SuppressWarnings("unused")
	private double sal;
	public final int sex = 0;

	// 构造器
	public Person() {
	}

	public Person(String name) {
	}

	// 私有的
	@SuppressWarnings("unused")
	private Person(String name, int age) {

	}

	// 方法
	public void m1(String name, int age, double sal) {

	}

	protected String m2() {
		return null;
	}

	void m3() {

	}

	@SuppressWarnings("unused")
	private void m4() {

	}
}
